#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import json
import numpy as np
import csv
import datetime
import logging
import re
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
from collections import Counter, defaultdict

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[logging.FileHandler("prevention_generator.log"), logging.StreamHandler()]
)
logger = logging.getLogger("prevention_generator")

class PreventionGenerator:
    """品牌危机预防机制生成器"""
    
    def __init__(self, brand_name=None, evaluation_results=None):
        """
        初始化预防机制生成器
        
        Args:
            brand_name: 品牌名称
            evaluation_results: 评估结果（可选，字典格式）
        """
        self.brand_name = brand_name
        self.evaluation_results = evaluation_results
        self.crisis_data = []
        self.failure_cases = []
        
        logger.info(f"初始化 {brand_name} 的预防机制生成器")
    
    def generate_mock_evaluation_results(self):
        """
        生成模拟评估结果用于测试和演示
        
        Returns:
            dict: 模拟的评估结果
        """
        logger.info("正在生成模拟评估结果")
        
        # 随机生成评分（1-5的范围内）
        response_speed_score = round(np.random.uniform(2, 4.5), 1)
        transparency_score = round(np.random.uniform(2, 4.5), 1)
        image_protection_score = round(np.random.uniform(2, 4.5), 1)
        
        # 计算综合得分
        comprehensive_score = round((response_speed_score * 0.3 + transparency_score * 0.3 + image_protection_score * 0.4), 1)
        
        # 生成总体评估
        overall_assessment = ""
        if comprehensive_score >= 4.5:
            overall_assessment = "优秀"
        elif comprehensive_score >= 3.5:
            overall_assessment = "良好"
        elif comprehensive_score >= 2.5:
            overall_assessment = "一般"
        elif comprehensive_score >= 1.5:
            overall_assessment = "较差"
        else:
            overall_assessment = "很差"
        
        # 生成各项建议
        if response_speed_score >= 4:
            response_recommendation = f"{self.brand_name}响应速度良好，基本控制了危机扩散"
        elif response_speed_score >= 3:
            response_recommendation = f"{self.brand_name}响应速度一般，对危机控制有一定延迟"
        else:
            response_recommendation = f"{self.brand_name}响应速度较慢，建议优化危机响应流程"
        
        if transparency_score >= 4:
            transparency_recommendation = f"{self.brand_name}沟通透明度高，公开了危机详情并承担责任"
        elif transparency_score >= 3:
            transparency_recommendation = f"{self.brand_name}沟通透明度良好，但可以提供更多细节和后续措施"
        else:
            transparency_recommendation = f"{self.brand_name}沟通透明度一般，建议提供更多危机细节并说明解决方案"
        
        if image_protection_score >= 4:
            image_recommendation = f"{self.brand_name}形象保护效果良好，危机后品牌形象有所提升"
        elif image_protection_score >= 3:
            image_recommendation = f"{self.brand_name}形象保护效果一般，危机后品牌形象基本恢复"
        else:
            image_recommendation = f"{self.brand_name}形象保护效果较差，建议加强后续公关措施"
        
        # 构建评估结果字典
        mock_results = {
            '综合得分': {
                '评分': comprehensive_score,
                '建议': '综合以下各项建议'
            },
            '响应速度': {
                '评分': response_speed_score,
                '建议': response_recommendation
            },
            '沟通透明度': {
                '评分': transparency_score,
                '建议': transparency_recommendation
            },
            '品牌形象保护': {
                '评分': image_protection_score,
                '建议': image_recommendation
            },
            '总体评估': {
                '评分': overall_assessment,
                '建议': f"{self.brand_name}危机处理整体表现{overall_assessment}，综合得分为{comprehensive_score}分（满分5分）"
            }
        }
        
        logger.info("已生成模拟评估结果")
        return mock_results
    
    def generate_mock_crisis_data(self, data_points=50):
        """
        生成模拟危机数据用于测试和演示
        
        Args:
            data_points: 要生成的数据点数量
            
        Returns:
            list: 模拟的危机数据
        """
        logger.info(f"正在生成{data_points}条模拟危机数据")
        
        # 设置基准日期
        base_date = datetime.now() - timedelta(days=30)
        
        # 危机类型
        crisis_types = ['产品质量问题', '产品安全事故', '价格争议', '虚假宣传', '服务态度']
        # 内容来源平台
        platforms = ['微博', '知乎', '新闻媒体', '官方网站', '官方微博']
        # 危机关键词
        crisis_keywords = ['质量问题', '缺陷', '投诉', '不满', '失败', '道歉', '召回']
        
        # 生成模拟数据
        data = []
        for i in range(data_points):
            is_crisis = np.random.random() < 0.7  # 70%的内容与危机相关
            data_type = np.random.choice(['news', 'social', 'official'], p=[0.3, 0.6, 0.1])
            
            # 发布时间（在30天内随机分布）
            days_offset = np.random.randint(0, 30)
            published_time = base_date + timedelta(days=days_offset)
            
            # 情感得分（危机相关内容更偏负面）
            sentiment_score = np.random.normal(-0.3, 0.3) if is_crisis else np.random.normal(0.2, 0.3)
            sentiment_score = max(-1.0, min(1.0, sentiment_score))  # 限制在[-1,1]范围内
            
            data.append({
                'data_type': data_type,
                'title': f"{self.brand_name}相关内容#{i}",
                'content': f"这是关于{self.brand_name}的一条模拟{data_type}内容" + (f"，涉及{np.random.choice(crisis_keywords)}" if is_crisis else ""),
                'source': f"模拟来源{i%10}",
                'published_time': published_time,
                'date': published_time.date(),
                'platform': np.random.choice(platforms),
                'sentiment_score': sentiment_score,
                'crisis_related': 1 if is_crisis else 0,
                'crisis_keyword': np.random.choice(crisis_keywords) if is_crisis else "",
                'brand_name': self.brand_name
            })
        
        logger.info(f"已生成{len(data)}条模拟危机数据")
        self.crisis_data = data
        return data
    
    def load_evaluation_results(self, results_file):
        """
        从CSV文件加载评估结果
        
        Args:
            results_file: 评估结果CSV文件路径
            
        Returns:
            是否成功加载
        """
        try:
            if os.path.exists(results_file):
                results = {}
                
                with open(results_file, 'r', encoding='utf-8') as f:
                    reader = csv.DictReader(f)
                    for row in reader:
                        # 如果是数字，转换为浮点数
                        score = row['评分']
                        try:
                            score = float(score)
                        except ValueError:
                            # 如果不是数字，保持为字符串
                            pass
                            
                        results[row['评估项目']] = {
                            '评分': score,
                            '建议': row['建议']
                        }
                
                self.evaluation_results = results
                logger.info(f"从 {results_file} 加载了评估结果")
                return True
            else:
                logger.warning(f"评估结果文件 {results_file} 不存在，将使用模拟数据")
                self.evaluation_results = self.generate_mock_evaluation_results()
                return True
            
        except Exception as e:
            logger.error(f"加载评估结果出错: {str(e)}，将使用模拟数据")
            self.evaluation_results = self.generate_mock_evaluation_results()
            return True
    
    def load_crisis_data(self, data_file):
        """
        加载危机数据
        
        Args:
            data_file: 危机数据CSV文件路径
            
        Returns:
            是否成功加载
        """
        try:
            if os.path.exists(data_file):
                data = []
                with open(data_file, 'r', encoding='utf-8') as f:
                    reader = csv.DictReader(f)
                    for row in reader:
                        # 转换日期和数值字段
                        try:
                            row['published_time'] = datetime.strptime(row['published_time'], '%Y-%m-%d %H:%M:%S')
                            row['date'] = row['published_time'].date()
                            row['sentiment_score'] = float(row['sentiment_score'])
                            row['crisis_related'] = int(row['crisis_related'])
                            data.append(row)
                        except (ValueError, KeyError) as e:
                            logger.warning(f"处理CSV行时出错: {e}")
                            continue
                
                self.crisis_data = data
                logger.info(f"从 {data_file} 加载了 {len(data)} 条危机数据")
                return True
            else:
                logger.warning(f"危机数据文件 {data_file} 不存在，将使用模拟数据")
                self.generate_mock_crisis_data()
                return True
            
        except Exception as e:
            logger.error(f"加载危机数据出错: {str(e)}，将使用模拟数据")
            self.generate_mock_crisis_data()
            return True
    
    def load_failure_cases(self, cases_file=None):
        """
        加载危机失败案例库
        
        Args:
            cases_file: 失败案例JSON文件路径
            
        Returns:
            是否成功加载
        """
        try:
            # 如果提供了文件路径，从文件加载
            if cases_file and os.path.exists(cases_file):
                with open(cases_file, 'r', encoding='utf-8') as f:
                    self.failure_cases = json.load(f)
                logger.info(f"从 {cases_file} 加载了 {len(self.failure_cases)} 个失败案例")
                return True
            
            # 否则，加载内置的默认案例
            self.failure_cases = [
                {
                    "brand": "蒙牛",
                    "industry": "食品饮料",
                    "crisis_type": "产品质量",
                    "description": "2008年三聚氰胺事件，蒙牛产品被检出含有三聚氰胺",
                    "failure_points": ["危机预警系统缺失", "质量监控不严", "应对不及时", "沟通不透明"],
                    "consequences": ["品牌形象严重受损", "销量下跌", "经济损失", "消费者信任丧失"],
                    "lessons": ["建立严格的质量监控体系", "建立危机预警机制", "制定危机应对预案", "保持透明沟通"]
                },
                {
                    "brand": "三星",
                    "industry": "电子科技",
                    "crisis_type": "产品安全",
                    "description": "2016年Galaxy Note 7电池爆炸事件",
                    "failure_points": ["质量控制不严", "应对决策拖延", "召回行动混乱", "危机扩大化"],
                    "consequences": ["品牌形象受损", "巨额经济损失", "市场份额下降"],
                    "lessons": ["强化产品安全测试", "快速决策响应机制", "完善召回流程", "透明沟通策略"]
                },
                {
                    "brand": "优衣库",
                    "industry": "服装零售",
                    "crisis_type": "公共关系",
                    "description": "2015年试衣间不雅视频事件",
                    "failure_points": ["危机应对不及时", "公关声明模糊", "社交媒体管控不足"],
                    "consequences": ["舆论危机", "店铺客流减少", "品牌形象负面"],
                    "lessons": ["建立社交媒体监测系统", "完善店内安全管理", "制定明确危机沟通策略"]
                },
                {
                    "brand": "小米",
                    "industry": "电子科技",
                    "crisis_type": "产品质量",
                    "description": "2016年小米手机发热问题，多用户反映手机严重发热甚至烫伤",
                    "failure_points": ["硬件设计不完善", "测试不充分", "初期回应模糊", "用户沟通不足"],
                    "consequences": ["负面评价增加", "销量影响", "竞品趁机攻击", "用户流失"],
                    "lessons": ["加强极端使用场景测试", "建立快速响应用户反馈机制", "增强产品热管理设计", "改进技术沟通策略"]
                },
                {
                    "brand": "特斯拉",
                    "industry": "汽车制造",
                    "crisis_type": "产品安全事故",
                    "description": "2021年特斯拉刹车失灵事件，多位车主反映行驶过程中出现刹车失灵",
                    "failure_points": ["危机沟通策略失误", "公关态度强硬", "社交媒体回应不当", "技术分析不透明"],
                    "consequences": ["用户信任下降", "舆论持续发酵", "销量受影响", "监管部门介入调查"],
                    "lessons": ["避免过度防御态度", "重视用户投诉与体验", "提高技术沟通透明度", "建立专业危机公关团队"]
                }
            ]
            
            # 检查是否需要特定品牌的案例
            brand_specific_cases = []
            if self.brand_name:
                brand_lower = self.brand_name.lower()
                # 特斯拉特定案例更多细节
                if "特斯拉" in brand_lower or "tesla" in brand_lower:
                    brand_specific_cases = [
                        {
                            "brand": "特斯拉",
                            "industry": "汽车制造",
                            "crisis_type": "维权事件",
                            "description": "2021年上海车展特斯拉车顶维权事件，车主因刹车失灵问题维权引发全国关注",
                            "failure_points": ["公关回应过于强硬", "危机沟通策略失误", "用户投诉处理机制不完善", "舆情应对不及时", "态度不够谦虚"],
                            "consequences": ["全国舆论发酵", "监管部门约谈", "销量下滑", "品牌形象受损", "维权行为增加"],
                            "lessons": ["危机公关需更加谦虚", "重视每一位用户投诉", "建立专业维权处理机制", "提高技术问题透明度", "培训员工正确沟通态度"]
                        }
                    ]
                # 小米特定案例更多细节
                elif "小米" in brand_lower or "xiaomi" in brand_lower:
                    brand_specific_cases = [
                        {
                            "brand": "小米",
                            "industry": "电子科技",
                            "crisis_type": "系统广告争议",
                            "description": "MIUI系统内置广告过多引发用户不满",
                            "failure_points": ["商业模式与用户体验失衡", "广告投放不够精准", "用户反馈机制不完善", "产品决策偏离用户需求"],
                            "consequences": ["用户体验下降", "品牌口碑受损", "老用户流失", "社交媒体负面讨论增加"],
                            "lessons": ["平衡商业利益与用户体验", "提供广告控制选项", "建立用户参与产品决策机制", "定期评估用户满意度"]
                        }
                    ]
                
                # 将特定品牌的案例添加到案例库
                if brand_specific_cases:
                    self.failure_cases.extend(brand_specific_cases)
            
            logger.info(f"加载了 {len(self.failure_cases)} 个内置失败案例")
            return True
            
        except Exception as e:
            logger.error(f"加载失败案例出错: {str(e)}")
            return False
    
    def analyze_crisis_patterns(self):
        """
        分析危机模式
        
        Returns:
            危机模式分析结果
        """
        if not self.crisis_data:
            logger.error("未加载危机数据，无法分析危机模式")
            return None
        
        try:
            # 提取危机相关内容
            crisis_content = [item for item in self.crisis_data if item['crisis_related'] == 1]
            
            if not crisis_content:
                logger.warning("未发现危机相关内容，无法分析模式")
                return None
            
            # 根据数据类型分析不同来源的危机信息
            source_distribution = {}
            for item in crisis_content:
                data_type = item['data_type']
                source_distribution[data_type] = source_distribution.get(data_type, 0) + 1
            
            # 分析危机关键词
            keywords = Counter()
            for item in crisis_content:
                if 'crisis_keyword' in item and item['crisis_keyword']:
                    keywords[item['crisis_keyword']] += 1
            
            # 分析危机时间分布
            time_distribution = {}
            for item in crisis_content:
                date = item['date']
                time_distribution[date] = time_distribution.get(date, 0) + 1
            
            # 按日期排序
            time_distribution = {k: time_distribution[k] for k in sorted(time_distribution.keys())}
            
            # 分析情感走势
            sentiment_by_source = defaultdict(list)
            for item in crisis_content:
                sentiment_by_source[item['data_type']].append(item['sentiment_score'])
            
            # 计算每种来源的平均情感得分
            for source in sentiment_by_source:
                scores = sentiment_by_source[source]
                sentiment_by_source[source] = sum(scores) / len(scores)
            
            # 提取危机类型模式（基于关键词和内容分析）
            crisis_types = self._identify_crisis_types(crisis_content)
            
            return {
                'source_distribution': source_distribution,
                'keywords': dict(keywords.most_common(10)),
                'time_distribution': time_distribution,
                'sentiment_by_source': dict(sentiment_by_source),
                'crisis_types': crisis_types
            }
            
        except Exception as e:
            logger.error(f"分析危机模式出错: {str(e)}")
            return None
    
    def _identify_crisis_types(self, crisis_data):
        """
        识别危机类型
        
        Args:
            crisis_data: 危机相关数据
            
        Returns:
            危机类型及其可能性
        """
        # 危机类型及其关键词
        crisis_type_keywords = {
            '产品质量问题': ['质量', '故障', '缺陷', '不良', '差', '坏', '问题'],
            '产品安全事故': ['安全', '事故', '爆炸', '起火', '受伤', '危险'],
            '价格争议': ['价格', '贵', '涨价', '降价', '促销', '退款'],
            '虚假宣传': ['虚假', '造假', '欺骗', '宣传', '广告', '误导'],
            '服务态度': ['服务', '态度', '差', '傲慢', '客服', '投诉'],
            '食品安全': ['食品', '安全', '卫生', '添加剂', '过期', '变质'],
            '数据泄露': ['数据', '泄露', '隐私', '信息', '安全', '黑客'],
            '企业形象': ['形象', '声誉', '丑闻', '负面', '公关', '舆论'],
            '劳资纠纷': ['员工', '工人', '劳资', '纠纷', '罢工', '抗议'],
            '环境问题': ['环境', '污染', '排放', '绿色', '可持续', '生态']
        }
        
        # 初始化结果
        crisis_types = defaultdict(int)
        
        # 遍历所有内容
        for item in crisis_data:
            if 'content' not in item or not isinstance(item['content'], str):
                continue
                
            content = item['content']
            # 检查每种危机类型的关键词
            for crisis_type, keywords in crisis_type_keywords.items():
                match_count = sum([1 for keyword in keywords if keyword in content])
                if match_count > 0:
                    crisis_types[crisis_type] += match_count
        
        # 标准化结果
        total = sum(crisis_types.values())
        if total > 0:
            normalized_types = {k: round(v/total, 2) for k, v in crisis_types.items()}
            return dict(sorted(normalized_types.items(), key=lambda x: x[1], reverse=True))
        
        return {}
    
    def find_similar_cases(self, crisis_types=None):
        """
        在失败案例库中查找相似案例
        
        Args:
            crisis_types: 危机类型（可选，如果为None则使用模式分析结果）
            
        Returns:
            相似案例列表
        """
        if not self.failure_cases:
            success = self.load_failure_cases()
            if not success:
                logger.error("未加载失败案例库，无法查找相似案例")
                return []
        
        # 如果未提供危机类型，使用模式分析来确定
        if not crisis_types:
            patterns = self.analyze_crisis_patterns()
            if patterns and 'crisis_types' in patterns:
                crisis_types = list(patterns['crisis_types'].keys())
            else:
                logger.warning("未提供危机类型且无法从数据中分析，将使用所有案例")
                return self.failure_cases
        
        # 寻找相似案例
        similar_cases = []
        for case in self.failure_cases:
            case_type = case.get('crisis_type', '').lower()
            
            # 检查是否为相同品牌
            is_same_brand = False
            if self.brand_name and 'brand' in case:
                case_brand = case['brand'].lower()
                brand_lower = self.brand_name.lower()
                is_same_brand = (case_brand in brand_lower) or (brand_lower in case_brand)
            
            # 检查危机类型是否相似
            is_similar_type = False
            if crisis_types:
                for crisis_type in crisis_types:
                    if isinstance(crisis_type, str) and crisis_type.lower() in case_type:
                        is_similar_type = True
                        break
            
            # 如果是相同品牌或相似危机类型，添加到结果中
            if is_same_brand or is_similar_type:
                similar_cases.append(case)
        
        logger.info(f"找到 {len(similar_cases)} 个相似案例")
        return similar_cases
    
    def generate_prevention_mechanism(self):
        """
        生成品牌危机预防机制
        
        Returns:
            预防机制字典
        """
        logger.info("开始生成预防机制")
        
        # 如果没有评估结果，生成模拟结果
        if not self.evaluation_results:
            self.evaluation_results = self.generate_mock_evaluation_results()
        
        # 获取评估分数
        response_speed_score = self.evaluation_results.get('响应速度', {}).get('评分', 3.0)
        transparency_score = self.evaluation_results.get('沟通透明度', {}).get('评分', 3.0)
        image_protection_score = self.evaluation_results.get('品牌形象保护', {}).get('评分', 3.0)
        
        # 确保评分是数值类型
        if not isinstance(response_speed_score, (int, float)):
            response_speed_score = 3.0
        if not isinstance(transparency_score, (int, float)):
            transparency_score = 3.0
        if not isinstance(image_protection_score, (int, float)):
            image_protection_score = 3.0
        
        # 分析危机模式
        crisis_patterns = self.analyze_crisis_patterns()
        
        # 如果无法分析模式，使用默认值
        if not crisis_patterns:
            crisis_patterns = {
                'crisis_types': {'产品质量问题': 0.5, '企业形象': 0.3, '虚假宣传': 0.2}
            }
        
        # 查找相似案例
        similar_cases = self.find_similar_cases(list(crisis_patterns.get('crisis_types', {}).keys()))
        
        # 预防机制的各个方面
        monitoring = self._generate_monitoring_mechanism(response_speed_score, crisis_patterns)
        response_team = self._generate_response_team(response_speed_score, transparency_score)
        communication = self._generate_communication_strategy(transparency_score, image_protection_score)
        recovery = self._generate_recovery_plan(image_protection_score)
        lessons = self._extract_lessons_from_cases(similar_cases)
        
        # 构建预防机制
        prevention_mechanism = {
            '危机监测机制': monitoring,
            '危机响应团队': response_team,
            '危机沟通策略': communication,
            '品牌恢复计划': recovery,
            '经验教训': lessons,
            '推荐案例研究': [case['description'] for case in similar_cases[:3]] if similar_cases else []
        }
        
        logger.info("预防机制生成完成")
        return prevention_mechanism
    
    def _generate_monitoring_mechanism(self, response_speed_score, crisis_patterns):
        """
        生成危机监测机制
        
        Args:
            response_speed_score: 响应速度评分
            crisis_patterns: 危机模式分析结果
            
        Returns:
            监测机制字典
        """
        # 基本监测内容
        basic_monitoring = [
            "建立社交媒体监测系统，追踪品牌相关关键词",
            "设置负面舆情预警阈值，当负面信息达到一定数量时触发预警",
            "定期分析消费者反馈和投诉数据"
        ]
        
        # 根据响应速度增加监测内容
        if response_speed_score < 3.0:
            advanced_monitoring = [
                "引入24小时舆情监测系统，确保及时发现潜在危机",
                "增加预警级别细分，针对不同类型的危机设置不同响应流程",
                "建立与主要媒体平台的直接沟通渠道，加快信息获取"
            ]
        else:
            advanced_monitoring = [
                "优化现有监测系统的响应速度，进一步缩短危机发现时间",
                "扩大监测关键词范围，覆盖更多潜在危机场景",
                "增加竞品监测，从竞争对手的危机中吸取经验"
            ]
        
        # 根据危机类型添加特定监测内容
        specific_monitoring = []
        if crisis_patterns and 'crisis_types' in crisis_patterns:
            for crisis_type in crisis_patterns['crisis_types']:
                if '质量' in crisis_type:
                    specific_monitoring.append("加强产品质量反馈渠道监测，在用户投诉初期识别潜在系统性问题")
                elif '安全' in crisis_type:
                    specific_monitoring.append("建立产品安全事故快速响应机制，关注安全相关关键词")
                elif '价格' in crisis_type:
                    specific_monitoring.append("监测价格相关讨论，及时发现定价策略引发的争议")
                elif '宣传' in crisis_type:
                    specific_monitoring.append("审核营销内容的真实性，监测虚假宣传相关投诉")
                elif '服务' in crisis_type:
                    specific_monitoring.append("监测客服满意度数据，识别服务态度问题")
                elif '形象' in crisis_type:
                    specific_monitoring.append("监测品牌声誉指标，建立品牌形象预警系统")
        
        # 合并监测内容
        monitoring_mechanism = {
            "基础监测": basic_monitoring,
            "针对性监测": specific_monitoring if specific_monitoring else ["基于历史数据建立品牌特定的监测指标"],
            "高级监测": advanced_monitoring
        }
        
        return monitoring_mechanism
    
    def _generate_response_team(self, response_speed_score, transparency_score):
        """
        生成危机响应团队
        
        Args:
            response_speed_score: 响应速度评分
            transparency_score: 沟通透明度评分
            
        Returns:
            响应团队字典
        """
        # 基本团队结构
        basic_team = [
            "危机管理负责人：整体协调危机应对流程",
            "公关传播专员：负责对外沟通和声明发布",
            "法律顾问：评估法律风险和应对策略",
            "客服主管：处理用户投诉和反馈"
        ]
        
        # 根据响应速度添加团队成员
        if response_speed_score < 3.0:
            speed_improvement = [
                "增设决策加速官：简化审批流程，确保快速响应",
                "建立24小时值班制度，确保随时可响应危机",
                "设立跨部门快速响应小组，减少沟通层级"
            ]
        else:
            speed_improvement = [
                "优化现有响应流程，设定关键响应时间节点",
                "定期进行危机演练，提高团队协作效率",
                "建立危机响应资源库，包含模板和应对方案"
            ]
        
        # 根据透明度评分添加团队成员
        if transparency_score < 3.0:
            transparency_improvement = [
                "增设信息披露官：负责确保危机沟通的透明度和一致性",
                "危机数据分析师：提供客观数据支持沟通内容",
                "用户关系专员：与受影响用户保持直接沟通"
            ]
        else:
            transparency_improvement = [
                "优化沟通审批流程，保持信息透明度的同时确保准确性",
                "建立危机沟通指南，规范各阶段的信息披露内容",
                "增强内部信息共享机制，确保一致的对外表述"
            ]
        
        # 合并团队结构
        response_team = {
            "核心成员": basic_team,
            "响应速度优化": speed_improvement,
            "透明度提升": transparency_improvement,
            "团队要求": [
                "明确的责任分工和决策链",
                "24小时联系机制",
                "定期培训和演练",
                "与外部专家的合作关系"
            ]
        }
        
        return response_team
    
    def _generate_communication_strategy(self, transparency_score, image_protection_score):
        """
        生成危机沟通策略
        
        Args:
            transparency_score: 沟通透明度评分
            image_protection_score: 品牌形象保护评分
            
        Returns:
            沟通策略字典
        """
        # 基本沟通原则
        basic_principles = [
            "及时性：在危机发生后尽快作出回应",
            "真实性：提供真实、准确的信息",
            "一致性：各渠道、各发言人保持信息一致",
            "同理心：表达对受影响方的关切和理解"
        ]
        
        # 根据透明度评分制定沟通策略
        if transparency_score < 3.0:
            transparency_strategy = [
                "提高信息披露主动性，不等问题扩大再回应",
                "建立分阶段信息发布机制，即使没有完整信息也及时沟通进展",
                "承认问题存在并明确后续解决方案",
                "避免技术性和模糊的语言，使用公众易于理解的表述"
            ]
        else:
            transparency_strategy = [
                "维持现有的透明沟通实践，进一步提高信息深度",
                "在危机沟通中加入专业解释和数据支持",
                "建立定期更新机制，持续通报危机处理进展",
                "适当展示内部处理流程，增强公众信任"
            ]
        
        # 根据品牌形象保护评分制定沟通策略
        if image_protection_score < 3.0:
            image_strategy = [
                "强化品牌核心价值在危机沟通中的体现",
                "准备危机后的正面信息传播计划",
                "识别并动员品牌拥护者参与正面沟通",
                "建立与意见领袖的沟通渠道，争取客观评价"
            ]
        else:
            image_strategy = [
                "保持品牌一贯的沟通风格，但增加真诚度",
                "在解决问题的同时展示品牌价值观",
                "将危机应对转化为品牌升级的机会",
                "危机后策划正面品牌故事的传播"
            ]
        
        # 沟通渠道
        channels = [
            "社交媒体：快速回应，广泛覆盖",
            "官方网站：发布详细声明和进展",
            "传统媒体：必要时接受采访和发布声明",
            "直接沟通：与重要利益相关方直接对话",
            "内部沟通：确保员工了解情况并统一口径"
        ]
        
        # 合并沟通策略
        communication_strategy = {
            "基本原则": basic_principles,
            "透明度策略": transparency_strategy,
            "形象保护策略": image_strategy,
            "沟通渠道": channels
        }
        
        return communication_strategy
    
    def _generate_recovery_plan(self, image_protection_score):
        """
        生成品牌恢复计划
        
        Args:
            image_protection_score: 品牌形象保护评分
            
        Returns:
            恢复计划字典
        """
        # 基本恢复措施
        basic_recovery = [
            "制定危机后的品牌传播计划",
            "针对受影响用户的补偿或关怀措施",
            "内部复盘总结，完善流程防止再次发生",
            "与主要利益相关方重建信任关系"
        ]
        
        # 根据品牌形象保护评分制定恢复计划
        if image_protection_score < 3.0:
            advanced_recovery = [
                "全面品牌形象修复计划，包括可能的品牌重塑",
                "邀请第三方机构进行独立评估，增强公信力",
                "推出能够体现品牌变革的新产品或服务",
                "积极参与社会责任活动，改善品牌公众形象",
                "建立长期的用户关系修复计划，逐步重建信任"
            ]
        else:
            advanced_recovery = [
                "强化现有的品牌优势，淡化危机影响",
                "危机后策划正面品牌故事的传播",
                "将危机解决方案转化为品牌价值的体现",
                "用数据证明品牌改进，发布透明的进展报告"
            ]
        
        # 持续监测指标
        monitoring_metrics = [
            "品牌提及情感分析",
            "用户满意度调查",
            "社交媒体参与度",
            "产品销售和市场份额变化",
            "媒体报道情感分析"
        ]
        
        # 合并恢复计划
        recovery_plan = {
            "基础恢复措施": basic_recovery,
            "深度恢复策略": advanced_recovery,
            "监测指标": monitoring_metrics,
            "时间框架": [
                "短期（1-2周）：危机直接应对和初步恢复",
                "中期（1-3个月）：系统性改进和品牌修复",
                "长期（3-12个月）：深度变革和持续监测"
            ]
        }
        
        return recovery_plan
    
    def _extract_lessons_from_cases(self, similar_cases):
        """
        从相似案例中提取经验教训
        
        Args:
            similar_cases: 相似案例列表
            
        Returns:
            经验教训列表
        """
        # 如果没有相似案例，返回通用经验
        if not similar_cases:
            return [
                "建立完善的危机预警和监测系统",
                "准备危机应对预案，包括沟通模板和流程",
                "培训危机应对团队，提高反应速度",
                "保持沟通透明，主动承担责任",
                "危机后及时总结经验，优化流程"
            ]
        
        # 从案例中提取经验教训
        all_lessons = []
        for case in similar_cases:
            if 'lessons' in case and isinstance(case['lessons'], list):
                all_lessons.extend(case['lessons'])
            
            if 'failure_points' in case and isinstance(case['failure_points'], list):
                # 将失败点转化为教训
                for point in case['failure_points']:
                    if "缺失" in point:
                        lesson = point.replace("缺失", "建立")
                    elif "不" in point:
                        lesson = point.replace("不", "")
                    else:
                        lesson = "避免" + point
                    all_lessons.append(lesson)
        
        # 去重和限制数量
        unique_lessons = []
        for lesson in all_lessons:
            if lesson not in unique_lessons:
                unique_lessons.append(lesson)
                if len(unique_lessons) >= 10:  # 最多返回10条经验
                    break
        
        return unique_lessons
    
    def save_prevention_mechanism(self, output_file):
        """
        保存预防机制到JSON文件
        
        Args:
            output_file: 输出文件路径
            
        Returns:
            是否成功保存
        """
        try:
            # 生成预防机制
            prevention_mechanism = self.generate_prevention_mechanism()
            
            # 保存到文件
            with open(output_file, 'w', encoding='utf-8') as f:
                json.dump(prevention_mechanism, f, ensure_ascii=False, indent=2)
            
            logger.info(f"预防机制已保存到 {output_file}")
            return True
            
        except Exception as e:
            logger.error(f"保存预防机制出错: {str(e)}")
            return False
    
    def plot_crisis_distribution(self, output_file='crisis_distribution.png'):
        """
        绘制危机分布图
        
        Args:
            output_file: 输出文件路径
            
        Returns:
            是否成功生成图表
        """
        if not self.crisis_data:
            logger.warning("没有数据，无法绘制危机分布")
            return False
        
        try:
            # 分析危机模式
            patterns = self.analyze_crisis_patterns()
            
            if not patterns:
                logger.warning("无法分析危机模式，无法绘制图表")
                return False
            
            # 创建图表（2x2布局）
            fig, axes = plt.subplots(2, 2, figsize=(14, 10))
            fig.suptitle(f"{self.brand_name} 危机分析", fontsize=16)
            
            # 1. 危机来源分布
            if 'source_distribution' in patterns and patterns['source_distribution']:
                sources = list(patterns['source_distribution'].keys())
                values = list(patterns['source_distribution'].values())
                
                axes[0, 0].pie(values, labels=sources, autopct='%1.1f%%', startangle=90)
                axes[0, 0].set_title('危机来源分布')
            
            # 2. 危机类型分布
            if 'crisis_types' in patterns and patterns['crisis_types']:
                types = list(patterns['crisis_types'].keys())
                proportions = list(patterns['crisis_types'].values())
                
                axes[0, 1].bar(types, proportions)
                axes[0, 1].set_title('危机类型分布')
                axes[0, 1].set_xticklabels(types, rotation=45, ha='right')
            
            # 3. 危机时间分布
            if 'time_distribution' in patterns and patterns['time_distribution']:
                dates = list(patterns['time_distribution'].keys())
                counts = list(patterns['time_distribution'].values())
                
                axes[1, 0].plot(dates, counts, marker='o', linestyle='-')
                axes[1, 0].set_title('危机时间分布')
                axes[1, 0].set_xticklabels([str(d) for d in dates], rotation=45, ha='right')
                axes[1, 0].grid(True, alpha=0.3)
            
            # 4. 情感分析
            if 'sentiment_by_source' in patterns and patterns['sentiment_by_source']:
                sent_sources = list(patterns['sentiment_by_source'].keys())
                sentiments = list(patterns['sentiment_by_source'].values())
                
                axes[1, 1].bar(sent_sources, sentiments)
                axes[1, 1].set_title('各来源情感分析')
                axes[1, 1].set_ylim(-1, 1)
                axes[1, 1].axhline(y=0, color='k', linestyle='-', alpha=0.3)
            
            # 调整布局
            plt.tight_layout()
            plt.subplots_adjust(top=0.9)
            
            # 保存图表
            plt.savefig(output_file)
            plt.close()
            
            logger.info(f"危机分布图已保存到 {output_file}")
            return True
            
        except Exception as e:
            logger.error(f"绘制危机分布图出错: {str(e)}")
            return False


if __name__ == "__main__":
    # 示例代码
    brand_name = "小米"
    
    # 创建预防机制生成器
    generator = PreventionGenerator(brand_name)
    
    # 生成模拟数据
    generator.generate_mock_crisis_data(100)
    
    # 加载失败案例
    generator.load_failure_cases()
    
    # 分析危机模式
    patterns = generator.analyze_crisis_patterns()
    if patterns:
        print("\n危机模式分析结果:")
        print(f"危机来源分布: {patterns['source_distribution']}")
        print(f"关键词: {patterns['keywords']}")
        print(f"危机类型: {patterns['crisis_types']}")
    
    # 生成并保存预防机制
    generator.save_prevention_mechanism(f"{brand_name}_prevention_mechanism.json")
    
    # 绘制危机分布图
    generator.plot_crisis_distribution(f"{brand_name}_crisis_distribution.png")
    
    print(f"\n已生成 {brand_name} 的品牌危机预防机制，文件保存为 {brand_name}_prevention_mechanism.json") 